/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.vdab.util;

import java.io.Serializable;
import java.text.DecimalFormat;

/**
 *
 * @author Joris.Lefever
 */
public final class Datum implements Comparable,Serializable {
    private final int fDag,fMaand,fJaar;
    private String foutMelding = "";
    private boolean testCase = false;
    //private final int fDag;
    //private final int fMaand;
    //private final int fJaar;
    
    
    public Datum(int aDag, int aMaand, int aJaar) throws DatumException{
        if (checkDatum(aDag,aMaand,aJaar)){
            throw new DatumException(foutMelding);
        } else {
            fDag = aDag;
            fMaand = aMaand;
            fJaar = aJaar;
        }
    }
    
    public boolean checkDatum(int aDag, int aMaand, int aJaar) {
        
        if (aDag < 0 | aDag > 31){
           foutMelding += "Day out of range. ";
           testCase = true;
        }
            
        if (aMaand < 0 | aMaand > 12){
            foutMelding +=  "Month out of range. ";
            testCase = true;
        }
            
        if (aJaar < 1583 | aJaar > 4099){
            foutMelding += "Year out of range. ";
            testCase = true;
        }
            
        if (aMaand == 2) {
            boolean schrikkeljaar = false;
            if (aJaar % 4 == 0){
                schrikkeljaar = true;
            }
            if (aJaar % 100 == 0){
                schrikkeljaar = false;
            }
            if (aJaar % 400 == 0){
               schrikkeljaar = true;
            }
            
            if (aDag == 29 & !schrikkeljaar){
                foutMelding += "This date does not exist, it is a leap year. ";
                testCase = true;
            } 
            if (aDag > 29){
                foutMelding += "This date does not exist, it is a leap year. ";
                testCase = true;
            } 
        }
           
        if ((aDag == 31) & (aMaand == 4 | aMaand == 6 | aMaand == 9 | aMaand == 11)) {
            foutMelding += "This month contains only 30 days. ";
            testCase = true;
        }
        return testCase;
    }
    
    public final int getDag() {
        return fDag;
    }
    
    public final int getMaand(){
        return fMaand;
    }
    
    public final int getJaar(){
        return fJaar;
    }
    
    @Override
    public final String toString(){
        DecimalFormat nft = new DecimalFormat("##00");  
        nft.setDecimalSeparatorAlwaysShown(false);
        return String.format("%s %s %s %s %s", nft.format(getDag()), " / ", nft.format(getMaand()), " / ", nft.format(getJaar()));
    }
    
    @Override
    public boolean equals(Object o){
         if (o == null)
            return false;
         else
            if (o instanceof Datum){
                Datum d = (Datum) o;
                if (getDag() == d.getDag() & getMaand() == d.getMaand() & getJaar() == d.getJaar())
                   return true;
                else
                   return false;
            }
            else
               return false;

    }
    
    @Override
    public int hashCode(){
       return toString().hashCode();
    }
    
    @Override 
    public int compareTo(Object o){
        if (o == null)
            throw new NullPointerException();
        else {
            Datum d = (Datum) o;
            if (getJaar()*10000 + getMaand()*100 + getDag() > d.getJaar()*10000 + d.getMaand()*100 + d.getDag())
                return 1;
            else {
                if (getJaar()*10000 + getMaand()*100 + getDag() < d.getJaar()*10000 + d.getMaand()*100 + d.getDag())
                    return -1;
                else 
                    return 0;
            }
        }
    }
    
}
